package cn.kgc.springcloud.service.impl;

import cn.kgc.springcloud.pojo.Faqs;
import cn.kgc.springcloud.service.FaqsRepository;
import cn.kgc.springcloud.service.FaqsService;
import cn.kgc.springcloudfaqs.FaqsVO;
import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class FaqsServiceImpl implements FaqsService {
    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Resource
    FaqsRepository faqsRepository;

    @RabbitListener(queues = "faqs")
    public void add(FaqsVO faqsVO, Message message, Channel channel) throws IOException {
        Faqs faqs = new Faqs();
        BeanUtils.copyProperties(faqsVO,faqs);
        faqsRepository.save(faqs);
        long deliverTag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck(deliverTag,false);
    }

    @Override
//    @Cacheable(cacheNames = "CACHE_10SEC")
    public Map<String,Object> selectPage(Integer pageNum, String title){

        System.out.println("pageNum:"+pageNum+"title:"+title);
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title",title);
        MatchQueryBuilder matchQueryBuilder1 = new MatchQueryBuilder("content",title);
        List<QueryBuilder> should = boolQueryBuilder.should();
        should.add(matchQueryBuilder);
        should.add(matchQueryBuilder1);

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<span style='color:red;'>");
        highlightBuilder.postTags("</span>");
        highlightBuilder.field("title");
        highlightBuilder.field("content");

        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withHighlightBuilder(highlightBuilder)
                .withPageable(PageRequest.of(pageNum-1,5))
                .build();
        AggregatedPage<Faqs> faqspages = elasticsearchRestTemplate.queryForPage(searchQuery, Faqs.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
                List<Faqs> faqsList = new ArrayList<>();
                SearchHits searchHits = searchResponse.getHits();
                if(searchHits==null||searchHits.totalHits==0){
                    System.out.println("等于空");
                    return null;
                }
                for (SearchHit searchHit : searchHits) {
                    System.out.println("有数据");
                    String sourceAsString = searchHit.getSourceAsString();
                    Faqs faqs = JSON.parseObject(sourceAsString, Faqs.class);
                    System.out.println("faqs:"+faqs);
                    //处理高亮
                    HighlightField title2 = searchHit.getHighlightFields().get("title");
                    if(title2!=null){
                        String title1 = title2.fragments()[0].toString();
                        faqs.setTitle(title1);
                    }
                    HighlightField content1 = searchHit.getHighlightFields().get("content");
                    if(content1!=null){
                        String content = content1.fragments()[0].toString();
                        faqs.setContent(content);
                    }
                    faqsList.add(faqs);

                }


                return new AggregatedPageImpl<T>((List<T>) faqsList,pageable,searchHits.getTotalHits());
            }

            @Override
            public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {
                return null;
            }
        });
        Map<String,Object> maps = new HashMap<>();
        List<Faqs> faqsList = null;
        if(faqspages!=null){
            faqsList = faqspages.toList();
            long totalElements = faqspages.getTotalElements();
            int pages = faqspages.getNumber()+1;

            maps.put("faqsVOList",faqsList);
            maps.put("totalElements",totalElements);
            maps.put("pages",pages);
        }else {
            maps.put("faqsVOList",null);
            maps.put("totalElements",0);
            maps.put("pages",1);
            return maps;
        }
        return maps;
    }
}
